use super::*;

#[test]
fn test_error_kind_code() {
    // 测试词法分析错误代码
    assert_eq!(ErrorKind::LexicalError.code(), "MY001");
    assert_eq!(ErrorKind::UnterminatedString.code(), "MY002");
    assert_eq!(ErrorKind::InvalidNumberFormat.code(), "MY003");
    assert_eq!(ErrorKind::InvalidIdentifier.code(), "MY004");
    assert_eq!(ErrorKind::UnterminatedComment.code(), "MY005");

    // 测试语法分析错误代码
    assert_eq!(ErrorKind::SyntaxError.code(), "MY100");
    assert_eq!(ErrorKind::UnexpectedToken.code(), "MY101");
    assert_eq!(ErrorKind::MissingToken.code(), "MY102");
    assert_eq!(ErrorKind::UnbalancedBrackets.code(), "MY103");
    assert_eq!(ErrorKind::InvalidStatement.code(), "MY104");
    assert_eq!(ErrorKind::UnexpectedEOF.code(), "MY105");
    assert_eq!(ErrorKind::InvalidIndentation.code(), "MY106");

    // 测试语义分析错误代码
    assert_eq!(ErrorKind::SemanticError.code(), "MY200");
    assert_eq!(ErrorKind::UndefinedIdentifier.code(), "MY201");
    assert_eq!(ErrorKind::AlreadyDefined.code(), "MY202");
    assert_eq!(ErrorKind::TypeMismatch.code(), "MY203");
    assert_eq!(ErrorKind::ArgumentMismatch.code(), "MY204");
    assert_eq!(ErrorKind::InvalidType.code(), "MY205");
    assert_eq!(ErrorKind::InvalidFunctionCall.code(), "MY206");
    assert_eq!(ErrorKind::UndefinedFunction.code(), "MY207");
    assert_eq!(ErrorKind::InvalidAssignment.code(), "MY208");
    assert_eq!(ErrorKind::OutOfScope.code(), "MY209");
    assert_eq!(ErrorKind::ConstantReassignment.code(), "MY210");
    assert_eq!(ErrorKind::InvalidInheritance.code(), "MY211");
    assert_eq!(ErrorKind::InterfaceNotImplemented.code(), "MY212");
    assert_eq!(ErrorKind::GenericError.code(), "MY213");
    assert_eq!(ErrorKind::InvalidOverride.code(), "MY214");
    assert_eq!(ErrorKind::AccessControlError.code(), "MY215");

    // 测试运行时错误代码
    assert_eq!(ErrorKind::RuntimeError.code(), "MY300");
    assert_eq!(ErrorKind::IndexOutOfBounds.code(), "MY301");
    assert_eq!(ErrorKind::DivisionByZero.code(), "MY302");
    assert_eq!(ErrorKind::NullReference.code(), "MY303");
    assert_eq!(ErrorKind::InvalidOperation.code(), "MY304");
    assert_eq!(ErrorKind::StackOverflow.code(), "MY305");
    assert_eq!(ErrorKind::RecursionDepthExceeded.code(), "MY306");
    assert_eq!(ErrorKind::FileNotFound.code(), "MY307");
    assert_eq!(ErrorKind::PermissionDenied.code(), "MY308");
    assert_eq!(ErrorKind::Timeout.code(), "MY309");

    // 测试模块和导入错误代码
    assert_eq!(ErrorKind::ImportError.code(), "MY400");
    assert_eq!(ErrorKind::ModuleNotFound.code(), "MY401");
    assert_eq!(ErrorKind::ExportError.code(), "MY402");
    assert_eq!(ErrorKind::CircularImport.code(), "MY403");
    assert_eq!(ErrorKind::InvalidModule.code(), "MY404");
    assert_eq!(ErrorKind::ModuleVersionMismatch.code(), "MY405");
    assert_eq!(ErrorKind::MissingExport.code(), "MY406");

    // 测试 IO 错误代码
    assert_eq!(ErrorKind::IOError.code(), "MY500");
    assert_eq!(ErrorKind::ReadError.code(), "MY501");
    assert_eq!(ErrorKind::WriteError.code(), "MY502");
    assert_eq!(ErrorKind::FileExists.code(), "MY503");
    assert_eq!(ErrorKind::InvalidPath.code(), "MY504");
    assert_eq!(ErrorKind::DirectoryError.code(), "MY505");
    assert_eq!(ErrorKind::EncodingError.code(), "MY506");

    // 测试警告和信息错误代码
    assert_eq!(ErrorKind::DeprecatedFeature.code(), "MY600");
    assert_eq!(ErrorKind::UnusedVariable.code(), "MY601");
    assert_eq!(ErrorKind::UnusedImport.code(), "MY602");
    assert_eq!(ErrorKind::UnreachableCode.code(), "MY603");
    assert_eq!(ErrorKind::UnusedFunction.code(), "MY604");
    assert_eq!(ErrorKind::ShadowingVariable.code(), "MY605");
    assert_eq!(ErrorKind::PerformanceWarning.code(), "MY606");
    assert_eq!(ErrorKind::CodeStyleWarning.code(), "MY607");
    assert_eq!(ErrorKind::DeprecatedSyntax.code(), "MY608");
    assert_eq!(ErrorKind::UnusedParameter.code(), "MY609");
    assert_eq!(ErrorKind::MissingDocumentation.code(), "MY610");

    // 测试信息提示代码
    assert_eq!(ErrorKind::InfoMessage.code(), "MY700");
    assert_eq!(ErrorKind::OptimizationHint.code(), "MY701");
    assert_eq!(ErrorKind::VersionInfo.code(), "MY702");
    assert_eq!(ErrorKind::DebugInfo.code(), "MY703");
    assert_eq!(ErrorKind::UsageInfo.code(), "MY704");
}

#[test]
fn test_error_kind_description() {
    // 测试错误类型描述
    assert_eq!(ErrorKind::LexicalError.description(), "词法错误");
    assert_eq!(ErrorKind::SyntaxError.description(), "语法错误");
    assert_eq!(ErrorKind::SemanticError.description(), "语义错误");
    assert_eq!(ErrorKind::RuntimeError.description(), "运行时错误");
    assert_eq!(ErrorKind::ImportError.description(), "导入错误");
    assert_eq!(ErrorKind::IOError.description(), "IO错误");
    assert_eq!(
        ErrorKind::DeprecatedFeature.description(),
        "使用了过时的特性"
    );
    assert_eq!(ErrorKind::InfoMessage.description(), "信息提示");
}

#[test]
fn test_compiler_error_creation() {
    // 测试编译器错误创建
    let error = CompilerError::new(
        ErrorKind::SyntaxError,
        "语法错误".to_string(),
        "test.moyan".to_string(),
        1,
        1,
        "let x = 1;".to_string(),
    );

    assert_eq!(error.kind, ErrorKind::SyntaxError);
    assert_eq!(error.level, ErrorLevel::Error);
    assert_eq!(error.message, "语法错误");
    assert_eq!(error.file_path, "test.moyan");
    assert_eq!(error.line, 1);
    assert_eq!(error.column, 1);
    assert_eq!(error.line_content, "let x = 1;");
    assert!(error.description.is_none());
    assert!(error.context.is_none());
    assert!(error.suggestion.is_none());
    assert!(error.note.is_none());
    assert!(error.span_length.is_none());
}

#[test]
fn test_compiler_error_with_fields() {
    // 测试编译器错误链式调用添加字段
    let error = CompilerError::new(
        ErrorKind::TypeMismatch,
        "类型不匹配".to_string(),
        "test.moyan".to_string(),
        1,
        1,
        "let x: int = \"string\";\n".to_string(),
    )
    .with_description("期望整数类型，但得到字符串类型".to_string())
    .with_context("变量x声明为int类型，但被赋值为字符串".to_string())
    .with_suggestion("请确保赋值类型与声明类型一致".to_string())
    .with_note("墨言语言是静态类型语言，需要显式类型声明".to_string())
    .with_span_length(15)
    .with_level(ErrorLevel::Error);

    assert_eq!(
        error.description,
        Some("期望整数类型，但得到字符串类型".to_string())
    );
    assert_eq!(
        error.context,
        Some("变量x声明为int类型，但被赋值为字符串".to_string())
    );
    assert_eq!(
        error.suggestion,
        Some("请确保赋值类型与声明类型一致".to_string())
    );
    assert_eq!(
        error.note,
        Some("墨言语言是静态类型语言，需要显式类型声明".to_string())
    );
    assert_eq!(error.span_length, Some(15));
    assert_eq!(error.level, ErrorLevel::Error);
}

#[test]
fn test_compiler_error_display() {
    // 测试编译器错误显示格式
    let error = CompilerError::new(
        ErrorKind::TypeMismatch,
        "类型不匹配".to_string(),
        "test.moyan".to_string(),
        1,
        1,
        "let x: int = \"string\";\n".to_string(),
    )
    .with_description("期望整数类型，但得到字符串类型".to_string())
    .with_suggestion("请确保赋值类型与声明类型一致".to_string());

    let error_str = format!("{}", error);
    assert!(error_str.contains("错误[MY203]"));
    assert!(error_str.contains("类型不匹配"));
    assert!(error_str.contains("--> test.moyan:1:1"));
}

#[test]
fn test_runtime_error_creation() {
    // 测试运行时错误创建
    let error = RuntimeError::new(ErrorKind::DivisionByZero, "不能除以零".to_string());

    assert_eq!(error.kind, ErrorKind::DivisionByZero);
    assert_eq!(error.message, "不能除以零");
    assert!(error.file_path.is_none());
    assert!(error.line.is_none());
    assert!(error.column.is_none());
    assert!(error.call_stack.is_empty());
    assert!(error.environment.is_none());
    assert!(error.suggestion.is_none());
    assert!(error.note.is_none());
}

#[test]
fn test_runtime_error_with_fields() {
    // 测试运行时错误链式调用添加字段
    let error = RuntimeError::new(ErrorKind::DivisionByZero, "不能除以零".to_string())
        .with_description("在除法操作中，除数为零".to_string())
        .with_location("test.moyan".to_string(), 10, 5)
        .with_suggestion("请添加除数不为零的检查".to_string())
        .with_note("除数为零是数学上的无效操作".to_string())
        .with_call_stack(vec![
            CallFrame {
                function_name: "main".to_string(),
                file_path: Some("test.moyan".to_string()),
                line: Some(10),
                column: Some(5),
            },
            CallFrame {
                function_name: "divide".to_string(),
                file_path: Some("test.moyan".to_string()),
                line: Some(5),
                column: Some(10),
            },
        ]);

    assert_eq!(
        error.description,
        Some("在除法操作中，除数为零".to_string())
    );
    assert_eq!(error.file_path, Some("test.moyan".to_string()));
    assert_eq!(error.line, Some(10));
    assert_eq!(error.column, Some(5));
    assert_eq!(error.suggestion, Some("请添加除数不为零的检查".to_string()));
    assert_eq!(error.note, Some("除数为零是数学上的无效操作".to_string()));
    assert_eq!(error.call_stack.len(), 2);
    assert_eq!(error.call_stack[0].function_name, "main");
    assert_eq!(error.call_stack[1].function_name, "divide");
}

#[test]
fn test_runtime_error_display() {
    // 测试运行时错误显示格式
    let error = RuntimeError::new(ErrorKind::DivisionByZero, "不能除以零".to_string())
        .with_location("test.moyan".to_string(), 10, 5)
        .with_suggestion("请添加除数不为零的检查".to_string());

    let error_str = format!("{}", error);
    assert!(error_str.contains("运行时错误[MY302]: 不能除以零"));
    assert!(error_str.contains("--> test.moyan:10:5"));
    assert!(error_str.contains("帮助: 请添加除数不为零的检查"));
}

#[test]
fn test_error_level_as_str() {
    // 测试错误级别字符串表示
    assert_eq!(ErrorLevel::Critical.as_str(), "严重错误");
    assert_eq!(ErrorLevel::Error.as_str(), "错误");
    assert_eq!(ErrorLevel::Warning.as_str(), "警告");
    assert_eq!(ErrorLevel::Info.as_str(), "信息");
}

#[test]
fn test_suggestion_generation() {
    // 测试智能建议生成
    let suggestion = SuggestionGenerator::generate_suggestion(
        ErrorKind::UndefinedIdentifier,
        "未定义的标识符: 'x'",
    );

    assert!(suggestion.is_some());
    assert!(suggestion.unwrap().contains("请检查 'x' 的拼写"));

    let suggestion = SuggestionGenerator::generate_suggestion(
        ErrorKind::TypeMismatch,
        "类型不匹配: 期望 int, 但得到 string",
    );

    assert!(suggestion.is_some());
}

#[test]
fn test_pattern_based_suggestion() {
    // 测试基于模式的建议生成
    let suggestion = SuggestionGenerator::generate_pattern_based_suggestion("未定义的标识符: 'x'");

    assert!(suggestion.is_some());
    assert!(suggestion.unwrap().contains("请检查变量名拼写"));

    let suggestion = SuggestionGenerator::generate_pattern_based_suggestion(
        "类型不匹配: 期望 int, 但得到 string",
    );

    assert!(suggestion.is_some());
    assert!(suggestion.unwrap().contains("请确保操作数类型兼容"));

    let suggestion = SuggestionGenerator::generate_pattern_based_suggestion(
        "参数数量不匹配: 期望 2 个参数, 但得到 1 个",
    );

    assert!(suggestion.is_some());
}

#[test]
fn test_warning_level_errors() {
    // 测试警告级别错误
    let error = CompilerError::new(
        ErrorKind::UnusedVariable,
        "未使用的变量 'x'".to_string(),
        "test.moyan".to_string(),
        1,
        5,
        "let x = 1;\n".to_string(),
    )
    .with_level(ErrorLevel::Warning);

    assert_eq!(error.level, ErrorLevel::Warning);
    assert_eq!(error.kind, ErrorKind::UnusedVariable);

    let error_str = format!("{}", error);
    assert!(error_str.contains("警告[MY601]: 未使用的变量 'x'"));
}

#[test]
fn test_info_level_errors() {
    // 测试信息级别错误
    let error = CompilerError::new(
        ErrorKind::OptimizationHint,
        "可以优化为更高效的代码".to_string(),
        "test.moyan".to_string(),
        1,
        1,
        "for i in 0..10 { ... }\n".to_string(),
    )
    .with_level(ErrorLevel::Info);

    assert_eq!(error.level, ErrorLevel::Info);
    assert_eq!(error.kind, ErrorKind::OptimizationHint);

    let error_str = format!("{}", error);
    assert!(error_str.contains("信息[MY701]: 可以优化为更高效的代码"));
}
